package com.example.gmall.search.listener;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.example.gmall.search.feign.GmallPmsClient;
import com.example.gmall.search.feign.GmallWmsClient;
import com.example.gmall.search.pojo.Goods;
import com.example.gmall.search.pojo.searchAttrValue;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class GoodsListener {
    @Resource
    private GmallPmsClient pmsClient;
    @Resource
    private GmallWmsClient wmsClient;
    @Resource
    private ElasticsearchRestTemplate restTemplate;
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("SEARCH.INSERT.QUEUE"),
            exchange = @Exchange(value = "PMS.SPU.EXCHANGE",type = ExchangeTypes.TOPIC,ignoreDeclarationExceptions = "true"),
            key = {"item.insert"}
    ))
    public void syncData(Long spuId, Channel channel, Message message) throws IOException {

            if (spuId == null){
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                return;
            }
        //根据spuId查询对象
        ResponseVo<SpuEntity> spuEntityResponseVo = pmsClient.querySpuById(spuId);
        SpuEntity spu = spuEntityResponseVo.getData();

        if (spu == null){
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            return;
        }


        ResponseVo<List<SkuEntity>> skuResponseVo = pmsClient.getById(spu.getId());
        List<SkuEntity> skus = skuResponseVo.getData();//获取sku的集合

        //同一个spu的sku品牌肯定是一样的，根据品牌id查询品牌
        ResponseVo<BrandEntity> brandEntityResponseVo = pmsClient.queryBrandById(spu.getBrandId());
        BrandEntity brandResponseVo = brandEntityResponseVo.getData();

        //同一个spu的sku分类肯定是一样的，根据分类id查询分类
        ResponseVo<CategoryEntity> categoryEntityResponseVo = pmsClient.queryCategoryById(spu.getCategoryId());
        CategoryEntity categoryResponseVo = categoryEntityResponseVo.getData();

        //根据spuid和cateid查询spu检索基本属性
        ResponseVo<List<SpuAttrValueEntity>> spuResponseVo
                = pmsClient.querySearchAttrValuesByCidAndSpuId(spu.getId(), spu.getCategoryId());
        List<SpuAttrValueEntity> spuAttrValueEntities = spuResponseVo.getData();

        //根据spuId查询spu下的skus
        restTemplate.save(skus.stream().map(sku->{
            Goods goods = new Goods();

            //设置sku的基本信息
            goods.setSkuId(sku.getId());
            goods.setTitle(sku.getTitle());
            goods.setSubTitle(sku.getSubtitle());
            goods.setDefaultImage(sku.getDefaultImage());
            goods.setPrice(sku.getPrice().doubleValue());

            //设置spu的创建时间
            goods.setCreateTime(spu.getCreateTime());
            //根据skuId查询库存，获取到销量及库存
            ResponseVo<List<WareSkuEntity>> wmsResponseVo
                    = wmsClient.getBySkuId(sku.getId());
            List<WareSkuEntity> wmss = wmsResponseVo.getData();
            if (CollectionUtils.isNotEmpty(wmss)){
                //销量
                goods.setSales(wmss.stream().map(WareSkuEntity::getSales)
                        .reduce((aLong, aLong2) -> aLong+aLong2).get());
                //是否有货
                goods.setStore(wmss.stream().anyMatch(wareSkuEntity->
                        wareSkuEntity.getStock()-(wareSkuEntity.getStockLocked()+wareSkuEntity.getSales()) > 0));
            }

            //设置品牌及分类
            if (brandResponseVo != null){
                //设置品牌参数
                goods.setBrandId(brandResponseVo.getId());
                goods.setBrandName(brandResponseVo.getName());
                goods.setLogo(brandResponseVo.getLogo());
            }
            if (categoryResponseVo != null){
                //设置分类参数
                goods.setCategoryId(categoryResponseVo.getId());
                goods.setCategoryName(categoryResponseVo.getName());
            }

            //设置检索类型的规格参数和值
            ArrayList<searchAttrValue> searchAttrValues = new ArrayList<>();
            //pms_sku_attr_value，当前sku的检索类型的销售属性和值
            ResponseVo<List<SkuAttrValueEntity>> skuAttrValeVo = pmsClient.querySearchAttrValuesByCidAndSkuId(sku.getCategoryId(), sku.getId());
            List<SkuAttrValueEntity> skuAttrValueEntities = skuAttrValeVo.getData();
            if (CollectionUtils.isNotEmpty(skuAttrValueEntities)){
                //转换集合类型并保存
                searchAttrValues.addAll(
                        skuAttrValueEntities.stream().map(skuAttrValueEntity -> {
                            searchAttrValue searchAttrValue = new searchAttrValue();
                            BeanUtils.copyProperties(skuAttrValueEntity,searchAttrValue);
                            return searchAttrValue;
                        }).collect(Collectors.toList()));
            }
            //pms_spu_attr_value，当前spu的检索类型的基本属性和值
            if (CollectionUtils.isNotEmpty(spuAttrValueEntities)){
                searchAttrValues.addAll(
                        spuAttrValueEntities.stream().map(spuAttrValueEntity -> {
                            searchAttrValue searchAttrValue = new searchAttrValue();
                            BeanUtils.copyProperties(spuAttrValueEntity,searchAttrValue);
                            return searchAttrValue;
                        }).collect(Collectors.toList()));
            }
            //保存检索类型的规格参数和值
            goods.setSearchAttrs(searchAttrValues);
            return goods;
        }).collect(Collectors.toList()));

        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}
